package com.iwhalecloud.citybrain.flow.platform.manager.infrastructure.utils;

import com.google.common.collect.Maps;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.exception.RemoteApiCallException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
import java.util.Objects;

/**
 * @author lich
 * @date 2021/11/11
 */
@Service
@Slf4j
public class RestTemplateWrapper {


    private static String SSO_SESSIONID = "xxl_sso_sessionid";

    @Autowired
    private RestTemplate restTemplate;


    public <T> T get(String url, Class<T> responseType) {
        return get(url, responseType, Maps.newHashMap());
    }

    public <T> T get(String url, Class<T> responseType, Map<String, Object> requestParam) {
        HttpHeaders headers = new HttpHeaders();
        headers.set("Accept", MediaType.APPLICATION_JSON_VALUE);
        HttpServletRequest httpServletRequest = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        if (Objects.nonNull(httpServletRequest)){
            Cookie[] cookies = httpServletRequest.getCookies();
            String cookieValue = null;
            for (Cookie cookie : cookies) {
                if (cookie.getName().equals(SSO_SESSIONID)) {
                    cookieValue = cookie.getName()+"="+cookie.getValue();
                }
            }
            if (StringUtils.isNotBlank(cookieValue)){
                headers.set(HttpHeaders.COOKIE,cookieValue);
            }
        }

        HttpEntity< ? > entity = new HttpEntity<>(headers);
        ResponseEntity<T> responseEntity;
        StringBuilder sb = new StringBuilder();
        sb.append(url);
        sb.append("?");
        for (Map.Entry<String, Object> entry : requestParam.entrySet()) {
            sb.append(entry.getKey() + "={" + entry.getKey() + "}");
            sb.append("&");
        }
        try {
            responseEntity = restTemplate.exchange(sb.toString(), HttpMethod.GET, entity, responseType, requestParam);
        } catch (Exception ex) {
            log.error("error requesting " + url, ex);
            throw new RemoteApiCallException(url + " request error", ex);
        }
        HttpStatus httpStatus = responseEntity.getStatusCode();
        if (!httpStatus.is2xxSuccessful()) {
            throw new RemoteApiCallException("status code is not 2xx: " + httpStatus.getReasonPhrase());
        }

        return responseEntity.getBody();
    }
}
